package com.kedacom.ctsp.authz.oauth2.provider;

import com.kedacom.ctsp.authz.entity.Authentication;
import com.kedacom.ctsp.authz.security.AuthzSecurityProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

/**
 * 在跳转登录之前拦截,如果已经sso单点登录了.则直接根据accessToken clientId clientSecret 获取用户信息
 *
 * @author fenghaiju
 * @create 2018/8/8
 **/
@Slf4j
public class RequestAuthenticationLoginFilter extends OncePerRequestFilter {
    private static String JWT_TOKEN = "jwt-token";
    @Autowired
    private AuthzSecurityProperties securityProperties;
    private String[] extenddAllUrl = {"/auth/login","/_ping", "/authy/checkLogin", "/auth/unauthorized","/static/global-config.json","/resource"};

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestUri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String url = requestUri.substring(contextPath.length());
        if (!isInclude(request)) {
            //当没有登录时候，判断是json请求还是其他请求
            if (!Authentication.current().isPresent() && !url.contains("/resource")) {

                String contentType = request.getContentType();
                String accept = request.getHeader("Accept");
                if (StringUtils.isNotBlank(contentType)) {
                    if ((MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(contentType)
                            || MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType)
                            || MediaType.APPLICATION_FORM_URLENCODED_VALUE.equalsIgnoreCase(contentType)
                            || contentType.contains(MediaType.APPLICATION_FORM_URLENCODED_VALUE))) {

                        if (!Arrays.asList(extenddAllUrl).contains(url)) {

                            response.sendRedirect(contextPath + securityProperties.getUnauthorizedUrl());
                            return;
                        } else {
                            filterChain.doFilter(request, response);
                            return;
                        }

                    }
                } else if (StringUtils.isNotBlank(accept) && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
                    if (!Arrays.asList(extenddAllUrl).contains(url)) {
                        response.sendRedirect(contextPath + securityProperties.getUnauthorizedUrl());
                        return;
                    }
                }
            }
        }
        filterChain.doFilter(request, response);
        return;
    }
    /**
     * 通过参数中是否存在accessToken, 并且accessToken有效 被过滤
     *
     * @param request
     * @return
     */
    private boolean isInclude(HttpServletRequest request) {
        String jwtToken = request.getHeader(JWT_TOKEN);
        if (StringUtils.isNotBlank(jwtToken)) {
            return true;
        }
        return false;
    }
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        // 暂时先不用,client不用切换
        return false;
//        return isInclude(request);
    }
}
